//
//  CheckerboardTransitionAnimator.swift
//  CustomTransitions
//
//  Created by fuyoufang on 2021/10/26.
//

import UIKit

// 投影
// https://blog.csdn.net/guyuealian/article/details/53954005

class CheckerboardTransitionAnimator: NSObject {
    
}

extension CheckerboardTransitionAnimator: UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 2
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        guard let toViewController = transitionContext.viewController(forKey: .to),
              let fromViewController = transitionContext.viewController(forKey: .from) else {
                  transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
                  return
              }
        
        let toView = transitionContext.view(forKey: .to)
        let fromView = transitionContext.view(forKey: .from)
        
        toView?.frame = transitionContext.finalFrame(for: toViewController)
        fromView?.frame = transitionContext.initialFrame(for: fromViewController)
        
        let containerView = transitionContext.containerView
                        
        if let toView = toView {
            containerView.addSubview(toView)
        }
        
        var fromViewSnapshot: UIImage?
        var toViewSnapshot: UIImage?
        
        UIGraphicsBeginImageContextWithOptions(containerView.bounds.size, true, containerView.window?.screen.scale ?? 2)
        fromView?.drawHierarchy(in: containerView.bounds, afterScreenUpdates: false)
        
        fromViewSnapshot = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        DispatchQueue.main.async {
            UIGraphicsBeginImageContextWithOptions(containerView.bounds.size, true, containerView.window?.screen.scale ?? 2)
            toView?.drawHierarchy(in: containerView.bounds, afterScreenUpdates: false)
            toViewSnapshot = UIGraphicsGetImageFromCurrentImageContext()
            UIGraphicsEndImageContext()

        }
        
        let transitionContainer = UIView(frame: containerView.bounds)
            .then {
                $0.isOpaque = true
                $0.backgroundColor = .black
            }
        
        containerView.addSubview(transitionContainer)
        
        var t = CATransform3DIdentity
        t.m34 = 1.0 / -900
        transitionContainer.layer.sublayerTransform = t
        
        let toContentLayer = CALayer()
        toContentLayer.frame = transitionContainer.bounds

        
        DispatchQueue.main.async {
            #warning("CATransaction  CATransition 分别是干啥的")
            let wereActiondDisabled = CATransaction.disableActions()
            
            CATransaction.setDisableActions(true)
            
            toContentLayer.rasterizationScale = toViewSnapshot?.scale ?? 0
            toContentLayer.contents = toViewSnapshot?.cgImage
            
            CATransaction.setDisableActions(wereActiondDisabled)
        }
        
        let toCheckboardSquareView = UIView(frame: transitionContainer.bounds)
            .then {
                $0.isOpaque = false
                $0.layer.masksToBounds = true
                $0.layer.isDoubleSided = false
                $0.layer.transform = CATransform3DMakeRotation(.pi, 0, 1, 0)
                $0.layer.addSublayer(toContentLayer)
            }
        transitionContainer.addSubview(toCheckboardSquareView)
        
        let fromContentLayer = CALayer()
        fromContentLayer.frame = transitionContainer.bounds
        fromContentLayer.rasterizationScale = fromViewSnapshot?.scale ?? 0
        fromContentLayer.contents = fromViewSnapshot?.cgImage
        
        let fromCheckboardSquareView = UIView(frame: transitionContainer.bounds)
            .then {
                $0.isOpaque = false
                $0.layer.masksToBounds = true
                #warning("todo isDoubleSided 作用？")
                $0.layer.isDoubleSided = false
                $0.layer.transform = CATransform3DIdentity
                $0.layer.addSublayer(fromContentLayer)
            }
        transitionContainer.addSubview(fromCheckboardSquareView)
        
        let transitionDuration = transitionDuration(using: transitionContext)
        UIView.animate(withDuration: transitionDuration) {
            toCheckboardSquareView.layer.transform = CATransform3DIdentity
            fromCheckboardSquareView.layer.transform = CATransform3DMakeRotation(.pi, 0, 1, 0)
        } completion: { finished in
            
            transitionContainer.removeFromSuperview()
            
            let wasCancelled = transitionContext.transitionWasCancelled
            transitionContext.completeTransition(!wasCancelled)
        }
    }
}
